package main

import (
	"cm2"
	"cm2/service"
	"cm2/service/log"
	"cm2/terminal/worker/win-web/global"
	"cm2/terminal/worker/win-web/taskclient"
	"fmt"
	"os"
	"os/signal"
	"path"
	"syscall"

	cmutil "cm2/util"

	"github.com/go-xorm/xorm"

	_ "github.com/mattn/go-sqlite3"
)

// Run 启动服务
func run() {
	defer func() {
		if recoverErr := recover(); recoverErr != nil {
			log.DefaultLogger().Fatalf("application failed, unhandled panic: %v", recoverErr)
			return
		}
	}()

	go func() {
		ch := make(chan os.Signal, 1)
		signal.Notify(ch,
			// kill -SIGINT XXXX or Ctrl+c
			os.Interrupt,
			syscall.SIGINT, // register that too, it should be ok
			// os.Kill  is equivalent with the syscall.Kill
			os.Kill,
			syscall.SIGKILL, // register that too, it should be ok
			// kill -SIGTERM XXXX
			syscall.SIGTERM,
		)
		select {
		case <-ch:
			shutdown()
		}
	}()

	log.DefaultLogger().Info("win-web worker service's starting, initializing...")

	// 初始化主服务实例
	service.Init()

	// 启动 job service
	taskclient.RunJobService(initJobLogProvider())

	// 启动 task tcp client
	taskclient.RunTaskService()

	<-global.TaskServShutdown
	log.DefaultLogger().Info("win-web worker service has been shutdown")
}

// Shutdown 停止端
func shutdown() {
	tc := service.DefaultTaskClient()
	if tc != nil {
		log.DefaultLogger().Info("shutting down task client service...")
		tc.Shutdown()
	}
	js := service.DefaultJobService()
	if js != nil {
		log.DefaultLogger().Info("shutting down job service...")
		js.Shutdown()
	}
	global.TaskServShutdown <- true
}

func initJobLogProvider() *xorm.Engine {
	// 开启log数据库连接，如果出现错误，直接抛出致命异常
	var jbp *xorm.Engine
	var jbpError error

	logPath := path.Join(cmutil.GetWorkingPath(), service.DefaultConfig["log"].(string))
	if exists, _ := cmutil.PathExists(logPath); !exists {
		cmutil.Mkdir(cmutil.GetDir(logPath))
		if f, _ := os.OpenFile(logPath, os.O_CREATE, 0777); f != nil {
			f.Close()
		}
	}

	if jbp, jbpError = xorm.NewEngine("sqlite3", logPath); jbpError != nil {
		em := fmt.Sprintf("init jblog provider failed: %v", jbpError)
		log.DefaultLogger().Error(em)
		panic(em)
	}
	if jbpError = jbp.Ping(); jbpError != nil {
		em := fmt.Sprintf("ping jblog failed: %v", jbpError)
		log.DefaultLogger().Error(em)
		panic(em)
	}
	if cmutil.GetGOENV() == cm2.DEV {
		jbp.ShowSQL(true)
		// js.jbp.SetLogger(xorm.NewLo) 好像不需要设置日志
	}

	return jbp
}

func main() {
	run()
}
